package com.ruoyi.project.WxMoudle.api;


import com.ruoyi.common.constant.WxConstant;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.wx.DateUtils;
import com.ruoyi.framework.config.MyConfig;
import com.ruoyi.framework.interceptor.annotation.IgnoreAuth;
import com.ruoyi.project.WebMoudle.WxShop.domain.WxShop;
import com.ruoyi.project.WebMoudle.WxShop.service.IWxShopService;
import com.ruoyi.project.WebMoudle.WxUser.domain.WxUser;
import com.ruoyi.project.WebMoudle.WxUser.service.IWxUserService;
import com.ruoyi.project.WebMoudle.accountDetails.domain.AccountDetails;
import com.ruoyi.project.WebMoudle.accountDetails.service.IAccountDetailsService;
import com.ruoyi.project.WebMoudle.onlineCoupon.domain.OnlineCoupon;
import com.ruoyi.project.WebMoudle.onlineCoupon.service.IOnlineCouponService;
import com.ruoyi.project.WebMoudle.streamShop.service.IStreamShopService;
import com.ruoyi.project.WebMoudle.vipCoupon.domain.VipCoupon;
import com.ruoyi.project.WebMoudle.vipCoupon.service.IVipCouponService;
import com.ruoyi.project.WebMoudle.wxOrder.domain.MyOrder;
import com.ruoyi.project.WebMoudle.wxOrder.domain.WxOrder;
import com.ruoyi.project.WebMoudle.wxOrder.service.IWxOrderService;
import com.ruoyi.project.WxMoudle.Bases.AppController;
import com.ruoyi.project.WxMoudle.Bases.WeixinConfig;
import com.ruoyi.project.sdk.WXPay;
import com.ruoyi.project.sdk.WXPayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

/*支付和订单的逻辑*/
@RestController
@RequestMapping(value = "/wx/order")
public class OrderController extends AppController {

    @Autowired
    private IWxOrderService orderService;
    @Autowired
    private IWxShopService shopService;
    @Autowired
    private IWxUserService wxUserService;
    @Autowired
    private IOnlineCouponService onlineCouponService;
    @Autowired
    private IVipCouponService vipCouponService;
    @Autowired
    private IAccountDetailsService accountDetailsService;
    @Autowired
    private IStreamShopService streamShopService;

    /*生成订单,并调取微信支付*/
    @RequestMapping(value = "/toPay")
    @ResponseBody
    @IgnoreAuth
    @Transactional
    public Object toPay(WxOrder order) {
        if (!StringUtils.isNotNull(order.getBeforePrice()) || !StringUtils.isNotNull(order.getShopId())
                || !StringUtils.isNotNull(order.getWxUserId()) || !StringUtils.isNotEmpty(order.getOpenId())) {
            return writeResultFailure("缺少参数传递");
        }
        /*计算实付金额-------------输入金额-积分兑换-优惠券*/
        WxShop wxShop = shopService.selectWxShopById(order.getShopId());
        BigDecimal money = order.getBeforePrice();      //本身价格
        BigDecimal convertMoney = new BigDecimal("0");   //积分转化金额
        if (StringUtils.isNotNull(order.getUseJifen())) {    //使用了积分
            WxUser user = wxUserService.selectWxUserById(order.getWxUserId());
            if (order.getUseJifen() > user.getJiFen()) {
                return writeResultFailure("积分不足");
            }

            convertMoney = BigDecimal.valueOf(order.getUseJifen()).divide(new BigDecimal("10"));
        }
        money = money.subtract(convertMoney);
        order.setConvertMoney(convertMoney);     //设置积分转化金额进行抵扣
        order.setShopDiscount(wxShop.getDiscountRatio());
        order.setOrderNum(OrderUtil.getGoodsOrderNo());

        BigDecimal reduceMoney = new BigDecimal("0");   //优惠券减免金额
        if (StringUtils.isNotNull(order.getCouponId())) {    //使用优惠券
            OnlineCoupon onlineCoupon = onlineCouponService.selectOnlineCouponById(order.getCouponId());
            System.out.println(onlineCoupon);
            if (order.getBeforePrice().doubleValue() < Double.parseDouble(onlineCoupon.getUseCondition())) {
                return writeResultFailure("优惠券不满足使用条件");
            }
            if (new Date().getTime() < onlineCoupon.getStartTime().getTime() || onlineCoupon.getStatus().equals("2")) {
                return writeResultFailure("优惠券已过期或者未开始使用");
            }
            //查询会员优惠券  ---修改状态
            VipCoupon vipCoupon = vipCouponService.selectMyCoupon(onlineCoupon.getId(), order.getWxUserId());
            if (vipCoupon == null) {
                return writeResultFailure("不存在此优惠券或者已使用");
            }
            reduceMoney =onlineCoupon.getReduceMoney();
        }
        money = money.subtract(reduceMoney);
        order.setReduceMoney(reduceMoney);    //设置优惠券抵扣金额

        if (money.compareTo(BigDecimal.ZERO) == -1) {
            return writeResultFailure("价格有误");
        }
        money =money.setScale(2, BigDecimal.ROUND_DOWN);
        order.setRealityPrice(money);
        /*=================测试时使用,上线后注释掉=====================*/

                    //money=new BigDecimal("0.01");

        /*=================测试时使用,上线后注释掉=====================*/
        order.setStatus(WxConstant.OD_PAY_NO);   //未支付状态
        int i = orderService.insertWxOrder(order);
        if (i > 0) {   //订单创建成功后调取支付接口
            //orderService.successPay(order); //测试使用
            Map<String, Object> map = this.getPreparyId("", order.getOpenId(), order.getOrderNum(), money.doubleValue(), "内" + wxShop.getShopName() + "消费");
            return map;
        }


        return writeResultFailure("创建订单失败");
    }


    @RequestMapping(value = "/successPay")
    @ResponseBody
    @IgnoreAuth
    public void successPay(HttpServletRequest request, HttpServletResponse response) {
        try {
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            response.setHeader("Access-Control-Allow-Origin", "*");//设置允许所有域名进行跨域访问
            //获取请求的输入流
            InputStream in = request.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];//创建缓存字节数组
            int len = 0;
            //读取输入流里面的数据
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            out.close();
            in.close();
            //读取out中的xml数据字符串
            String requestXml = new String(out.toByteArray(), "utf-8");
            MyConfig config = new MyConfig();
            WXPay wxpay = new WXPay(config);
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(requestXml);
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
                //签名合法正确
                //将requestXml数据转换成wxChatRefundApiResult对象bean
                WechatRefundApiResult wechatRefundApiResult = (WechatRefundApiResult) XmlUtil.xmlStrToBean(requestXml, WechatRefundApiResult.class);
                String result_code = wechatRefundApiResult.getResult_code();
                if (result_code.equalsIgnoreCase("FAIL")) {
                    //返回标识如果未失败
                    System.out.println("回调订单支付失败");
                    return;
                } else if (result_code.equalsIgnoreCase("SUCCESS")) {
                    System.out.println("回调订单支付成功");
                    //订单编号
                    String orderNum = wechatRefundApiResult.getOut_trade_no();
                    String cardId = wechatRefundApiResult.getAttach();

                    //根据订单编号查询订单
                    WxOrder wxOrder = orderService.selectWxOrderByOrderNum(orderNum);
                    //检测订单是否已经为已支付状态，是否已经分润，防止多次回调
                    if (wxOrder.getStatus().equals(WxConstant.OD_PAY_YES)) {
                        //已经支付
                        response.getWriter().write(setXml("SUCCESS", "OK"));
                        return;
                    }
                    if (wxOrder != null) {
                        //修改wxOrder状态
                        /******************插入分钱逻辑,返还积分************************/
                        Boolean flag = orderService.successPay(wxOrder);
                        if (flag) {
                            //回调的逻辑操作都成功
                            response.getWriter().write(setXml("SUCCESS", "OK"));
                        } else {
                            //回调的逻辑操作不成功
                            for (int f = 0; f < 50; f++) {
                                System.out.println("回调逻辑报错");
                            }
                        }

                    } else {
                        return;
                    }
                } else {
                    return;
                }
            } else {
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
    }

    /*查询用户的订单列表*/
    @RequestMapping(value = "/queryMyOrderList")
    @ResponseBody
    @IgnoreAuth
    public Object queryMyOrderList(Long wxUserId) {
        WxOrder wxOrder = new WxOrder();
        wxOrder.setWxUserId(wxUserId);
        List<WxOrder> list = orderService.queryMyOrderList(wxOrder);
        return list;
    }

    /*用户查询订单详情*/
    @RequestMapping(value = "/queryOneOrder")
    @ResponseBody
    @IgnoreAuth
    public Object queryOneOrder(Long orderId) {
        WxOrder wxOrder = orderService.selectWxOrderById(orderId);
        return wxOrder;
    }

    /*商家查询订单详情*/
    @RequestMapping(value = "/queryOrderDetail")
    @ResponseBody
    @IgnoreAuth
    public Object queryOrderDetail(Long orderId) {
        MyOrder wxOrder = orderService.queryOrderDetail(orderId);
        return wxOrder;
    }
    /*根据订单编号查询*/
    @RequestMapping(value = "/queryListByNum")
    @ResponseBody
    @IgnoreAuth
    public Object queryListByNum(String orderNum,Long wxUserId) {
        WxOrder wxOrder = new WxOrder();
        wxOrder.setOrderNum(orderNum);
        wxOrder.setWxUserId(wxUserId);
        List<WxOrder> list = orderService.queryMyOrderList(wxOrder);
        return list;
    }

    /*查询店铺的订单*/
    @RequestMapping(value = "/queryShopOrderList")
    @ResponseBody
    @IgnoreAuth
    public Object queryShopOrderList(Long shopId ) {
        List<MyOrder> list =orderService.queryShopOrderList(shopId);
        return list;
    }
    /*查询商家收款*/
    @RequestMapping(value = "/queryMoneyList")
    @ResponseBody
    @IgnoreAuth
    public Object queryMoneyList(Long shopId,String myMoth) {
        HashMap<Object, Object> map = new HashMap<>();
        List<AccountDetails> list =accountDetailsService.queryMoneyList(shopId,myMoth);
        BigDecimal monthMoney = new BigDecimal("0");
        for (AccountDetails accountDetails : list) {
            monthMoney= monthMoney.add(accountDetails.getShopMoney());
        }
        map.put("list",list);
        map.put("monthMoney",monthMoney);
        return map;
    }
    /*查询店铺的返利订单*/
    @RequestMapping(value = "/queryReturnOrder")
    @ResponseBody
    @IgnoreAuth
    public Object queryReturnOrder(Long shopId) {
        List<Map> list =streamShopService.queryReturnOrder(shopId);
        return list;
    }

    //获取预支付id
    public Map<String, Object> getPreparyId(String attach, String openid, String orderNum, Double price, String msg) {
        try {
            Map<String, String> resultObj = new TreeMap<>();//装载返回给页面的参数
            Map<String, String> data = new HashMap<String, String>();//装载请求接口的参数
            StringBuffer body = new StringBuffer("在有有积分");
            body.append(msg);
            data.put("body", body.toString());
            data.put("out_trade_no", orderNum);//订单编号
            data.put("device_info", msg);
            //设备号，存储自定义终端信息
            data.put("attach", attach);
            data.put("fee_type", "CNY");
            //支付金额,精准计算出转换为分为单位的价钱数值
            BigDecimal bigDecimal = new BigDecimal(price + "");
//           BigDecimal bigDecimal=new BigDecimal(0.01+"");
            String total_fee = bigDecimal.multiply(new BigDecimal("100")).intValue() + "";
            data.put("total_fee", total_fee);//支付金额
            data.put("openid", openid);
            data.put("spbill_create_ip", WeixinConfig.SPBILL_CREATE_IP);
            data.put("notify_url", WeixinConfig.NOTIFY_URL);    //回调路径
            data.put("trade_type", WeixinConfig.TRADE_TYPE);  // 此处指定为JSAPI支付
            MyConfig config = new MyConfig();
            WXPay wxPay = new WXPay(config);
            Map<String, String> resp = wxPay.unifiedOrder(data);
            System.out.println("下单接口调用返回参数");
            System.out.println(resp);
            if (resp.get("return_code").equalsIgnoreCase("FAIL")) {
                //接口调用失败
                System.out.println("调用预支付接口调用失败");
                return writeResultFailure("调接口失败," + resp.get("return_msg"));
            } else if (resp.get("return_code").equalsIgnoreCase("SUCCESS")) {
                System.out.println("调用预支付接口调用成功");
                String result_code = resp.get("result_code");//返回结果标识
                if (result_code.equalsIgnoreCase("FAIL")) {
                    System.out.println("获取预支付id出错");
                    return writeResultFailure("获取预支付id失败,");
                } else if (result_code.equalsIgnoreCase("SUCCESS")) {
                    System.out.println("获取预支付id成功");
                    String prepay_id = resp.get("prepay_id");//预支付id
                    // 先生成paySign参数map
                    resultObj.put("appId", WeixinConfig.APPID);
                    //时间戳
                    resultObj.put("timeStamp", DateUtils.timeToStr(System.currentTimeMillis() / 1000, DateUtils.DATE_TIME_PATTERN));
                    String nonceStr = WXPayUtil.generateNonceStr();//获取随机字符串
                    resultObj.put("nonceStr", nonceStr);
                    resultObj.put("package", "prepay_id=" + prepay_id);
                    resultObj.put("signType", "HMACSHA256");
                    //此处根据返回的结果，和预支付id在此生成支付签证
                    String paySign = WXPayUtil.generateSignature(resultObj, WeixinConfig.PAYKEY);
                    resultObj.put("paySign", paySign);
                    return writeResultRep(resultObj, "预支付id获取成功");
                } else {
                    System.out.println("获取预支付id出错");
                    return writeResultFailure("获取预支付id失败,");
                }
            } else {
                System.out.println("调用预支付接口出现无法识别的错误");
                return writeResultFailure("调接口失败," + resp.get("return_msg"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return writeResultFailure("系统错误");
        }
    }

    //返回微信服务
    public static String setXml(String return_code, String return_msg) {
        return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
    }



}
